/**
 * This file is part of Too-OneBee.
 *
 * Too-OneBee is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Too-OneBee is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Too-OneBee.  If not, see <http://www.gnu.org/licenses/>.
 */
package net.dataforte.tooonebee.jmx;

import static net.dataforte.tooonebee.Menu.menu;

import java.io.PrintWriter;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.Map.Entry;

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.dataforte.tooonebee.Menu;
import net.dataforte.tooonebee.ServiceIntrospector;

public class JMXIntrospector extends ServiceIntrospector {
	List<MBeanServer> servers;

	@Override
	public void init(ServletConfig config) {
		servers = MBeanServerFactory.findMBeanServer(null);
	}

	@Override
	public String getRequestPath() {
		return "jmx";
	}
	
	@Override
	public Set<Menu> getMenuEntries() {
		Set<Menu> entries = super.getMenuEntries();
		entries.add(
			menu("JMX", this.getRequestPath())
		);
		return entries;
	}

	@Override
	public void handleRequest(HttpServlet servlet, HttpServletRequest req, HttpServletResponse res) throws Exception {
		res.setContentType("text/xml; UTF-8");
		PrintWriter writer = res.getWriter();
		writer.println("<servers>");
		for (MBeanServer server : servers) {
			writer.printf("<server>\n");

			Set<ObjectName> mBeans = server.queryNames(null, null); // new
																	// TreeSet<ObjectInstance>();
			Set<String> mBeanNames = new TreeSet<String>();

			for (ObjectName mBean : mBeans) {
				StringBuilder sb = new StringBuilder(mBean.getDomain() + ":");
				Hashtable<String, String> keyProperties = mBean.getKeyPropertyList();
				// If a "type" key is present, add it in the first position
				boolean separator = false;
				String type = keyProperties.remove("type");
				if (type != null) {
					sb.append("type=");
					sb.append(type);
					separator = true;
				}
				// We will add name at the end
				String name = keyProperties.remove("name");
				for (Entry<String, String> entry : keyProperties.entrySet()) {
					if (separator) {
						sb.append(",");
					}
					sb.append(entry.getKey());
					sb.append("=");
					sb.append(entry.getValue());
					separator = true;
				}
				if (name != null) {
					if (separator) {
						sb.append(",");
					}
					sb.append("name=");
					sb.append(name);
				}
				mBeanNames.add(sb.toString());
			}

			for (String mBeanName : mBeanNames) {
				writer.printf("<mbean><![CDATA[%s]]></mbean>\n", mBeanName);
			}

			writer.println("</server>");
		}
		writer.println("</servers>");
	}

}
